package com.sweetcircle.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sweetcircle.domain.dto.MessageSendDto;
import com.sweetcircle.domain.dto.TokenUserInfoDto;
import com.sweetcircle.domain.enums.MessageTypeEnum;
import com.sweetcircle.domain.enums.UserStatusEnum;
import com.sweetcircle.domain.po.UserInfo;
import com.sweetcircle.domain.query.UserInfoQuery;
import com.sweetcircle.domain.vo.UserInfoLoginVO;
import com.sweetcircle.domain.vo.UserInfoVO;
import com.sweetcircle.exception.BusinessException;
import com.sweetcircle.mapper.UserInfoMapper;
import com.sweetcircle.service.UserInfoService;
import com.sweetcircle.utils.AnanUtils;
import com.sweetcircle.utils.PinyinUtils;
import com.sweetcircle.utils.RedisComponet;
import com.sweetcircle.websocket.MessageHandler;
import jakarta.annotation.Resource;
import org.apache.catalina.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
* @author hp
* @description 针对表【user_info(用户信息)】的数据库操作Service实现
* @createDate 2024-07-28 13:24:03
*/
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private RedisComponet redisComponet;

    @Resource
    private MessageHandler messageHandler;

    @Override
    public UserInfo getUserInfoByEmail(String email) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getEmail, email));
    }

    @Override
    public UserInfo getUserInfoByuserSweetCircleId(String userSweetCircleId) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserSweetCircleId, userSweetCircleId));
    }


    @Override
    @Transactional(rollbackFor =Exception.class)
    public HashMap<String, Object> login(UserInfoLoginVO userInfoLoginVO) {
        HashMap<String, Object> data = new HashMap<>();
        // 根据邮箱查询用户信息
        UserInfo userInfo = getUserInfoByEmail(userInfoLoginVO.getEmail());
        if (userInfo == null) {
            throw new BusinessException(400, "邮箱未注册");
        }
        if (UserStatusEnum.DISABLE.getStatus().equals(userInfo.getStatus())) {
            throw new BusinessException(400, "该邮箱已禁用");
        }
        if (!AnanUtils.MD5Encryption(userInfoLoginVO.getPassword()).equals(userInfo.getPassword())) {
            throw new BusinessException(400, "密码错误");
        }


        //查询联系人
        ArrayList<HashMap<String, Object>> contactList = getAllContact(userInfo.getUserId());


        // 判断用户是否已经登录
        Long lastHeartBeat = redisComponet.getUserHeartBeat(userInfo.getUserId());
        if (lastHeartBeat != null) {
            data.put("alreadyLogin", true);
        }

        // 根据用户当前token 查看redis中的用户信息
        TokenUserInfoDto tokenUserInfoDto = redisComponet.getTokenUserInfoDto(userInfoLoginVO.getToken());
        if (tokenUserInfoDto!=null){  // redis中存在 该用户 那
            AnanUtils.copyBean(userInfo, tokenUserInfoDto);  // 将userInfo中的信息覆盖到tokenUserInfoDto中
            tokenUserInfoDto.setToken(userInfoLoginVO.getToken());  // 不在重新生成登录token
        }else{  // 不存在该用户信息 重新生成token
            tokenUserInfoDto = AnanUtils.copyBean(userInfo, TokenUserInfoDto.class);  // 将userInfo中的信息拷贝到tokenUserInfoDto中
            tokenUserInfoDto.setToken(AnanUtils.getId());
        }
        // 查看该用户是否是 管理员
        tokenUserInfoDto.setAdmin(AnanUtils.verifyAdministrator(userInfo.getEmail()));
        // 保存用户信息到redis中
        redisComponet.saveTokenUserInfoDto(tokenUserInfoDto);

        // 将用户信息转换为VO对象 返回给前端
        UserInfoVO userInfoVO = AnanUtils.copyBean(userInfo, UserInfoVO.class);
        userInfoVO.setToken(tokenUserInfoDto.getToken());
        userInfoVO.setAdmin(tokenUserInfoDto.getAdmin());
        redisComponet.removeCaptcha(userInfoLoginVO.getCaptchaKey());

        data.put("contactList", contactList);
        data.put("userInfo", userInfoVO);

        return data;
    }

    @Override
    @Transactional(rollbackFor =Exception.class)
    public void register(UserInfoLoginVO userInfoLoginVO) {
        Date curDate = new Date();  // 获取当前时间
        // 查询邮箱是否存在
        if (getUserInfoByEmail(userInfoLoginVO.getEmail()) != null) {
            throw new BusinessException(400, "邮箱已注册");
        }

        // 创建对象 用于保存在数据库
        UserInfo userInfo = AnanUtils.copyBean(userInfoLoginVO, UserInfo.class);
        String id = AnanUtils.getId();
        String userSweetCircleId = AnanUtils.getRandomString(ThreadLocalRandom.current().nextInt(6, 16));
        // 查看生成的ID 是否存在
        while (userInfoMapper.selectById(id) != null){
            id = AnanUtils.getId();
        }
        while (userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserSweetCircleId, userSweetCircleId)) != null) {
            userSweetCircleId = AnanUtils.getRandomString(ThreadLocalRandom.current().nextInt(6, 16));
        }
        // 重新设置密码 对密码加密
        userInfo.setPassword(AnanUtils.MD5Encryption(userInfoLoginVO.getPassword()));
        userInfo.setUserId(id);
        userInfo.setUserSweetCircleId(userSweetCircleId);
        userInfo.setCreateTime(curDate);
        userInfo.setLastLoginTime(curDate);
        // 插入数据
        Integer insert = userInfoMapper.insert(userInfo);
        if (insert == 0) {
            throw new BusinessException(400, "注册失败");
        }
    }

    @Override
    public void resetPassword(UserInfoLoginVO userInfoLoginVO) {
        String password = AnanUtils.MD5Encryption(userInfoLoginVO.getPassword());
        UserInfo userInfo = getUserInfoByEmail(userInfoLoginVO.getEmail());
        if (userInfo == null) {
            throw new BusinessException(400, "邮箱未注册");
        }
        if (UserStatusEnum.DISABLE.getStatus().equals(userInfo.getStatus())) {
            throw new BusinessException(400, "该邮箱已禁用");
        }
        if(password.equals(userInfo.getPassword())){
            throw new BusinessException(400, "新密码不能与旧密码相同");
        }
        UserInfo u = new UserInfo();
        u.setPassword(password);
        int update = userInfoMapper.update(u,new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getEmail, userInfoLoginVO.getEmail()));
        if (update == 0) {
            throw new BusinessException(400, "重置密码失败");
        }
    }

    @Override
    public void updateUserInfo(UserInfoVO userInfoVO) {
        UserInfo userInfo = AnanUtils.copyBean(userInfoVO, UserInfo.class);
        int i = userInfoMapper.update(userInfo, new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, userInfo.getUserId()));

        if(i<1){
            throw new BusinessException(400,"用户信息更新失败");
        }
        redisComponet.saveTokenUserInfoDto(AnanUtils.copyBean(userInfo, TokenUserInfoDto.class));
    }

    @Override
    public ArrayList<HashMap<String, Object>> getAllContact(String userId) {
        String s = "在开始编写代码之前我们需要使用Java的拼音转换库来将汉字转换为对应的拼音这里我们将使用第三方库pinyin4j来实现拼音转换功能首先我们需要将该库添加到我们的Java项目中可以通过在项目的构建文件比如Maven的pom.xml中添加相应的依赖来完成这一步骤";
        List<UserInfoVO> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            int a = Integer.parseInt(AnanUtils.getRandomNumber(1));
            int b = Integer.parseInt(AnanUtils.getRandomNumber(1)) + a + 5;
            UserInfoVO userInfoVO = new UserInfoVO();
            userInfoVO.setUserId(AnanUtils.getRandomNumber(10));
            userInfoVO.setEmail(AnanUtils.getRandomNumber(10) + "@qq.com");
            userInfoVO.setUserSweetCircleId(AnanUtils.getRandomNumber(10));
            userInfoVO.setNickName(s.substring(a, b));
            userInfoVO.setSex(ThreadLocalRandom.current().nextInt(0, 2));
            userInfoVO.setPersonalSignature("走自己的路不管别人的");
            userInfoVO.setAvatar("ycc011.jpg");
            userInfoVO.setAreaCode("10090");
            userInfoVO.setJoinType(1);
            userInfoVO.setAreaName("四川 成都");
            list.add(userInfoVO);
        }


        HashMap<String, List<UserInfoVO>> stringListMap = PinyinUtils.sortFirstLetterUserInfo(list);
        ArrayList<HashMap<String, Object>> res = new ArrayList<>();
        String[] array = stringListMap.keySet().toArray(new String[0]);
        for (int i = 0; i < array.length; i++) {
            HashMap<String, Object> map = new HashMap<>();
            String key = array[i];
            map.put("title", key);
            map.put("value", stringListMap.get(key));
            res.add(map);
        }
        Collections.sort(res, new Comparator<HashMap<String, Object>>() {
            @Override
            public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
                String o = (String) o1.get("title");
                String o3 = (String) o2.get("title");
                int c = o.charAt(0);
                int c1 = o3.charAt(0);

                return c > c1 ? 1 : -1;
            }
        });

        return res;
    }
}




